/***************************************************************************************************
  *Copyright(C),2010-2016,Sumscope
  *FileName	:  JsonWriter.h
  *Author	:  scofined.qi
  *Version	:  1.0
  *Date		:  2016/09/12
  *Desc		:  //用于主要说明此程序文件完成的主要功能
  *Relation :  
  *Others	:  //其他内容说明
  *Function :  //主要函数列表，每条记录应包含函数名及功能简要说明
  *History	:  //修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简介
***************************************************************************************************/
#ifndef JSONWRITER_H_EC400FCA_F023_453A_B43A_A285B2F8442A
#define JSONWRITER_H_EC400FCA_F023_453A_B43A_A285B2F8442A

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "simple_array.h"

namespace qb{
	namespace base{
class JsonWriter{		// 将json转化为字符串
public:
	typedef char Element;
	typedef qb::base::SimpleArray<Element> Buffer;
	typedef JsonWriter Writer;
protected:
	bool					m_finished;
	bool					m_rootmap;
	bool					m_rootlist;
	bool					m_format;
	int						m_count;			// 等级
	int						m_level;
	Buffer*					m_buffer;
public:
	class JsonWriterMap;
	class JsonWriterList{
		Writer*		m_writer;
		int					m_count;
	public:
		JsonWriterList(Writer* writer) :m_writer(writer), m_count(0){
			if (writer)
				writer->SetLevel(writer->GetLevel() + 1);
		}
		~JsonWriterList()
		{
			End();
		}
		void End();

		Writer* AddMap(){ AddHead(); return m_writer; }
		Writer* AddList(){ AddHead(); return m_writer; }
		void AddString(const Element* str, int len = 0){ AddHead(); m_writer->AddJsonString(str, len); }
		void AddBool(bool bvalue){ AddHead(); m_writer->AddBool(bvalue); }
		void AddInt(int ivalue){ AddHead(); m_writer->AddInt(ivalue); }
		void AddUint(unsigned int uvalue){ AddHead(); m_writer->AddUint(uvalue); }
		void AddUint64(unsigned long long u64){ AddHead(); m_writer->AddUint64(u64); }
		void AddInt64(long long ivalue){ AddHead(); m_writer->AddInt64(ivalue); }
		void AddDouble(double dvalue){ AddHead(); m_writer->AddDouble(dvalue); }
		void AddHead();
	};
	class JsonWriterMap{
		Writer*		m_writer;
		int				m_count;
	public:
		JsonWriterMap(Writer* writer) :m_writer(writer), m_count(0){
			if (writer)
				writer->SetLevel(writer->GetLevel() + 1);
		}
		~JsonWriterMap()
		{
			End();
		}
		void End();
		Writer* AddMap(const Element* name){AddHeadAndName(name);return m_writer; }
		Writer* AddList(const Element* name){ AddHeadAndName(name); return m_writer; }
		void AddString(const Element* name, const Element* str, int len = 0)
		{
			AddHeadAndName(name);
			m_writer->AddJsonString(str, len);
		}
		void AddBool(const Element* name, bool bvalue)
		{
			AddHeadAndName(name);
			m_writer->AddBool(bvalue);
		}
		void AddInt(const Element* name, int ivalue,int len=0)			{
			AddHeadAndName(name,len);
			m_writer->AddInt(ivalue);
		}
		void AddUint(const Element* name, unsigned int uvalue){
			AddHeadAndName(name);
			m_writer->AddUint(uvalue);
		}
		void AddUint64(const Element* name, unsigned long long u64){
			AddHeadAndName(name);
			m_writer->AddUint64(u64);
		}
		void AddInt64(const Element* name, long long ivalue){
			AddHeadAndName(name);
			m_writer->AddInt64(ivalue);
		}
		void AddDouble(const Element* name, double dvalue){
			AddHeadAndName(name);
			m_writer->AddDouble(dvalue);
		}
		void AddHead();
		void AddHeadAndName(const Element* name,int len=0);
	};
private:
	JsonWriter(const JsonWriter& jw){};
	JsonWriter& operator=(const JsonWriter& jw){ return *this; }
public:
	typedef JsonWriterList List;
	typedef JsonWriterMap Map;
	JsonWriter(int initCapcity = 0);
	~JsonWriter();
	void Reset();
	int GetCapcity()const;
	int GetBytes()const{return m_buffer?m_buffer->size():0;}
	void Start(int capcity);
	void SeekPos(int pos);
	void SetFormat(){ m_format = true; }
	const Element* c_str();
	int size();

	Writer* AddRootList(){m_rootlist=true;m_rootmap=false;return this;}
	Writer* AddRootMap(){ m_rootlist=false;m_rootmap = true;return this; }
	Writer* AddMap(const Element* name);
	Writer* AddList(const Element* name);
protected:
	int GetLevel()const{ return m_level; }
	void SetLevel(int level){ m_level = level; }
	void AddNewLine();
	void AddName(const Element* name, int len = 0);
	void AddJsonString(const Element* str, int len = 0);
	void AddString(const Element* str, int len = 0);
	void AddBool(bool bvalue){ AddString(bvalue ? "true" : "false", bvalue ? 4 : 5); }
	void AddInt(int ivalue){ Element buf[64] = { 0 }; sprintf(buf, "%d", ivalue); AddString(buf); }
	void AddUint(unsigned int uvalue){ Element buf[64] = { 0 }; int len = sprintf(buf,"%u", uvalue); AddString(buf, len); }
	void AddUint64(unsigned long long u64){ Element buf[64] = { 0 }; sprintf(buf, "%llu", u64); AddString(buf); }
	void AddInt64(long long ivalue){ Element buf[64] = { 0 }; sprintf(buf, "%lld", ivalue); AddString(buf); }
	void AddDouble(double dvalue){ Element buf[64] = { 0 }; int len = sprintf(buf, "%f", dvalue); AddString(buf, len); }
};
}//namespace base;
}//namespace qb;
#endif
